home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / mnyth3 / mnythdll.cpp < prev    next >
C/C++ Source or Header  |  1994-08-07  |  14KB  |  582 lines

  1. /*
  2.     Mnythdll.dll -- 7-31-94, Bruce McLean
  3.  
  4.     DLL for manythings screen saver, includes routines:
  5.  
  6.         1) ManyDibLoad -- reads DIB files into memory
  7.         2) ManyGifLoad -- reads GIF files into memory and converting to
  8.                              DIB format
  9.         3) ManyDibWrite -- writes DIB file in memory out to a file
  10.         4) ManyDibModPalette -- adds offsets to colors in palette
  11.         5) ManyDibCyclePalette -- shifts palette entries
  12.         6) ManyLoadLogPal -- retrieves DIB palette into a LOGPALETTE
  13.                                                         structure
  14.         7) ManyDibGet -- returns pointer to DIB in memory
  15.         8) ManyDibGetData -- returns pointer to bitmap data area of DIB in memory
  16.         9) ManyDibFree -- frees memory used by DIB in memory
  17.  
  18.     Warnings --
  19.         C++ by default modifies the names of functions to add parameter type
  20.             information, to make the functions callable by Visual Basic they need
  21.             to be declared as 'extern "C"' and 'pascal _export'.  See Mnythdll.h
  22.             for example.
  23.  
  24.         To use the project file, Directories under the Options menu will have to
  25.             be changed.
  26.  
  27. */
  28.  
  29. #define  STRICT
  30. #include <windows.h>
  31. #include <windowsx.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include "mnythdll.h" // function prototypes for declaring as exported "C"
  35. #include    "bitmaps.h"
  36. #include "gif.h"
  37.  
  38. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  39.  
  40. // static DIB data
  41. BYTE huge * DIBPointer;
  42. int Width,Height;
  43. const int NumColors = 256;
  44.  
  45. // Write DIB to a file from memory, returns 0 on no error
  46. int FAR pascal _export ManyDibWrite (const FAR char * szFileName)
  47. {
  48.     FILE * WriteFile;
  49.  
  50.     if(DIBPointer == NULL)
  51.     {
  52.         return 1;
  53.     }
  54.  
  55.     WriteFile = fopen(szFileName,"wb");
  56.     if(WriteFile == NULL)
  57.     {
  58.         return 2;
  59.     }
  60.  
  61.     // get header pointer
  62.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  63.  
  64.   // get total file size
  65.     unsigned long Size = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
  66.             + BMapHeader->biClrUsed * sizeof (RGBQUAD) + BMapHeader->biSizeImage;
  67.  
  68.   //write type to file
  69.     fputc('B',WriteFile);
  70.     fputc('M',WriteFile);
  71.  
  72.     fwrite(&Size,4,1,WriteFile); // store file size
  73.  
  74.     // file reserved fields
  75.     fputc(0,WriteFile);
  76.     fputc(0,WriteFile);
  77.     fputc(0,WriteFile);
  78.     fputc(0,WriteFile);
  79.  
  80.     // get offset to data bits
  81.     unsigned long Offset = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
  82.       + BMapHeader->biClrUsed * sizeof (RGBQUAD);
  83.  
  84.     fwrite(&Offset,4,1,WriteFile); // store file size
  85.  
  86.     //write dib
  87.     const unsigned int WriteMaxSize = 32768u;
  88.     unsigned long DibSize = BMapHeader->biSize + BMapHeader->biSizeImage
  89.         + BMapHeader->biClrUsed * sizeof (RGBQUAD);
  90.     unsigned int BlockSize;
  91.     BYTE huge * OutPointer = DIBPointer;
  92.  
  93.     while(DibSize > 0)
  94.     {
  95.         if(DibSize > WriteMaxSize)
  96.         {
  97.             BlockSize = WriteMaxSize;
  98.         }
  99.         else
  100.         {
  101.             BlockSize = (unsigned int) DibSize;
  102.         }
  103.  
  104.         fwrite(OutPointer,BlockSize,1,WriteFile); // store dib data
  105.  
  106.         DibSize -= BlockSize;
  107.         OutPointer += BlockSize;
  108.  
  109.   } // while end
  110.  
  111.     fclose(WriteFile);
  112.  
  113.     return 0; // success
  114.  
  115. }
  116.  
  117. // Read a dib palette into Logical palette for Vbasic
  118. void pascal _export ManyLoadLogPal (LOGPALETTE & Pal,int Start,int MaxSize,int Flags)
  119. {
  120.     Pal.palVersion = 0x0300;
  121.  
  122.     if( DIBPointer == NULL )
  123.     {
  124.         Pal.palNumEntries = 0;
  125.         return;
  126.     }
  127.  
  128.     // get header pointer
  129.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  130.  
  131.     // get Palette pointer
  132.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  133.  
  134.     BYTE huge * BPtr;
  135.  
  136.     Pal.palNumEntries = BMapHeader->biClrUsed;
  137.  
  138.   // check for funny palette size
  139.     if( (Pal.palNumEntries <= 0) || (Pal.palNumEntries >256) )
  140.     {
  141.         Pal.palNumEntries = 0;
  142.         return;
  143.     }
  144.  
  145.     if(Pal.palNumEntries > MaxSize)
  146.     {
  147.         Pal.palNumEntries = MaxSize;
  148.     }
  149.  
  150.     Pal.palNumEntries -= Start; // subtract off entries skipped
  151.  
  152.     // extract palette
  153.     for(int i=0;i<Pal.palNumEntries;i++)
  154.     {
  155.         BPtr = Palette + (i+Start)*4; // get address of palette entry
  156.  
  157.         Pal.palPalEntry[i].peRed = *(BPtr+2);
  158.         Pal.palPalEntry[i].peGreen = *(BPtr+1);
  159.         Pal.palPalEntry[i].peBlue = (*BPtr);
  160.         Pal.palPalEntry[i].peFlags = Flags;
  161.  
  162.         // set flags in palete
  163.         *(BPtr+3) = Flags;
  164.     }
  165. } // end ManyLoadLogPal
  166.  
  167. // Read a GIF from a file into memory
  168. long FAR pascal _export ManyGifLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
  169. {
  170.  
  171.     int i = ManyDibFree();
  172.     if(i != 0) // free memory
  173.     {
  174.         return -6-i; // error codes 1 to n are mapped to -7 to -7-n
  175.   }
  176.  
  177.     // read gif file into memory
  178.     HDIB DibHandle = ReadGifFile(szFileName);
  179.  
  180.     if(DibHandle == NULL)
  181.     {
  182.     return -1;
  183.     }
  184.  
  185.     BITMAPINFOHEADER huge * BMapHeader    = (BITMAPINFOHEADER huge *) GlobalLock(DibHandle);
  186.     DIBPointer = (BYTE huge *) BMapHeader;
  187.  
  188.     if(DIBPointer == NULL)
  189.     {
  190.     return -2;
  191.     }
  192.  
  193.     // check if wrong style dib
  194.     if ((BMapHeader->biSize != 0x28 ) // check for funny header size
  195.          || (BMapHeader->biPlanes != 1)  // check for multiple planes
  196.          || (BMapHeader->biBitCount != 8) // make sure 256 color
  197.          || (BMapHeader->biClrUsed > 256) // check for consistency
  198.          || (BMapHeader->biClrUsed <= 0) ) // check for consistency
  199.     {
  200.         ManyDibFree(); // free memory
  201.         return -5 ;
  202.   }
  203.  
  204.     int Width = (int) BMapHeader->biWidth;
  205.     int Height = (int) BMapHeader->biHeight;
  206.  
  207.     *height = Height;
  208.     *width = Width;
  209.  
  210.     return (long) DIBPointer ;
  211.  
  212. } // end ManyGifLoad
  213.  
  214. // Read a DIB from a file into memory
  215. long FAR pascal _export ManyDibLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
  216. {
  217.   BITMAPFILEHEADER bmfh ;
  218.     DWORD            dwDibSize, dwOffset;
  219.   int              hFile ;
  220.   WORD             wDibRead ;
  221.  
  222.     int i = ManyDibFree();
  223.     if(i != 0) // free memory
  224.     {
  225.         return -6-i; // error codes 1 to n are mapped to -7 to -7-n
  226.   }
  227.  
  228.     // try to open file
  229.     if (-1 == (hFile = _lopen (szFileName, OF_READ | OF_SHARE_DENY_WRITE)))
  230.     {
  231.         return -6 ;
  232.   }
  233.  
  234.   if (_lread (hFile, (LPSTR) &bmfh, sizeof (BITMAPFILEHEADER)) !=
  235.                                                                              sizeof (BITMAPFILEHEADER))
  236.   {
  237.     _lclose (hFile) ;
  238.     return -1 ;
  239.   }
  240.  
  241.   if (bmfh.bfType != * (WORD *) "BM")
  242.   {
  243.     _lclose (hFile) ;
  244.     return -2 ;
  245.   }
  246.  
  247.   dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ;
  248.  
  249.     DIBPointer = (BYTE huge * ) GlobalAllocPtr (GMEM_MOVEABLE, dwDibSize) ;
  250.  
  251.     if (DIBPointer == NULL)
  252.   {
  253.     _lclose (hFile) ;
  254.     return -3 ;
  255.   }
  256.  
  257.   dwOffset = 0 ;
  258.  
  259.   while (dwDibSize > 0)
  260.   {
  261.         wDibRead = (WORD) MIN (32768ul, dwDibSize) ;
  262.  
  263.         if (wDibRead != _lread (hFile, (LPSTR) (DIBPointer + dwOffset), wDibRead))
  264.     {
  265.       _lclose (hFile) ;
  266.             ManyDibFree();
  267.       return -4 ;
  268.     }
  269.  
  270.     dwDibSize -= wDibRead ;
  271.     dwOffset  += wDibRead ;
  272.   }
  273.  
  274.   _lclose (hFile) ;
  275.  
  276.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  277.  
  278.   // check if wrong style dib
  279.     if ((BMapHeader->biSize != 0x28 ) // check for funny header size
  280.          || (BMapHeader->biPlanes != 1)  // check for multiple planes
  281.          || (BMapHeader->biBitCount != 8) // make sure 256 color
  282.          || (BMapHeader->biClrUsed > 256) // check for consistency
  283.          || (BMapHeader->biClrUsed <= 0) ) // check for consistency
  284.     {
  285.         ManyDibFree();
  286.         return -5 ;
  287.   }
  288.  
  289.     Width = (int) BMapHeader->biWidth;
  290.     Height = (int) BMapHeader->biHeight;
  291.  
  292.     *height = Height;
  293.     *width = Width;
  294.  
  295.     return (long) DIBPointer ;
  296. }
  297.  
  298. // returns pointer to memory for DIB data bytes
  299. long FAR pascal _export ManyDibGetData( void )
  300. {
  301.  
  302.     if(DIBPointer == NULL) // see if not allocated
  303.     {
  304.         return NULL;
  305.     }
  306.  
  307.     // get header pointer
  308.     BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
  309.  
  310.     // get Palette pointer
  311.     BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
  312.  
  313.     // get data pointer
  314.     BYTE huge * DataBits = Palette + BMapHeader->biClrUsed * sizeof (RGBQUAD) ;
  315.  
  316.     return (long) DataBits; // no error, return pointer to data
  317.  
  318. }
  319.  
  320. // returns pointer to memory for DIB bitmap, also is pointer to header
  321. long FAR pascal _export ManyDibGet( void )
  322. {
  323.     return (long) DIBPointer; // return pointer
  324. }
  325.  
  326. // frees memory for DIB bitmap, returns 0 if successful
  327. int FAR pascal _export ManyDibFree( void )
  328. {
  329.     if(DIBPointer == NULL) // see if memory allocated
  330.     {
  331.         return 0; // no need to do